/*
 * Spring 2012 TCSS360 Deliverable 3
 * Richard Nguyen
 */

package gui;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Calendar;
import java.util.List;
import java.util.Locale;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SpringLayout;

import model.Auction;
import model.CalendarModel;
import model.NPOStaffMember;
import model.UserAccess;
import storage.ProgramStateHandler;
import exceptions.AuctionLimitReachedException;
import exceptions.BadDateException;
import exceptions.BadTimeException;
import exceptions.SameNpoInYearException;

@SuppressWarnings("serial")
public class AuctionFormGUI extends JPanel {

	private static final String TITLE =
			"Create a New Auction";

	private static final String ERROR = "Error";

	private static final String NPO_NAME = "NPO";

	/** Title of the Phone Number label */
	private static final String PHONE = "Phone Number";

	private static final String AUCTION_DATE =
			"Auction Date";

	private static final String START_TIME = "Start Time";

	private static final String END_TIME = "End Time";

	private static final String NUMBER_ITEMS =
			"Number of Items";

	private static final String COMMENT =
			"           Comments  ";

	private static final String SUBMIT = "Submit";

	private static final String CLEAR = "Clear";

	private static final int HOUR_IN_DAY = 24;

	private static final int MIN_IN_HOUR = 60;

	private static final int TEXT_FIELD_SIZE = 10;

	private static final int PHONE_NUM_SIZE = 3;

	private static final int YEARS_FUTURE = 20;

	private static final int COMMENT_COL = 370;

	private static final int COMMENT_ROW = 80;

	private static final String[] MONTHS = {"January",
			"February", "March", "April", "May", "June",
			"July", "August", "September", "October",
			"Novenber", "December"};

	private final JTextField my_npo_name;
	private final JTextField my_phone_number1;
	private final JTextField my_phone_number2;
	private final JTextField my_phone_number3;
	private final JComboBox my_month;
	private final JComboBox my_day;
	private final JComboBox my_year;
	private final JComboBox my_start_hour;
	private final JComboBox my_start_min;
	private final JComboBox my_end_hour;
	private final JComboBox my_end_min;
	private final JTextField my_number_items;
	private final JTextArea my_comment;

	private final JButton my_submit;
	private final JButton my_clear;
	private final JFrame my_Frame = new JFrame(TITLE);

	private CalendarModel my_cldmodel;

	private NPOStaffMember my_user;

	private UserAccess my_ua;

	private ProgramStateHandler my_ps;

	public AuctionFormGUI(final CalendarModel the_model,
			final ProgramStateHandler ps,
			final UserAccess ua, final NPOStaffMember user) {
		super();
		my_Frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		my_Frame.setResizable(false);
		setLayout(new BorderLayout());
		my_cldmodel = the_model;
		my_user = user;

		my_npo_name = new JTextField(TEXT_FIELD_SIZE);

		my_phone_number1 = new JTextField(PHONE_NUM_SIZE);
		my_phone_number2 = new JTextField(PHONE_NUM_SIZE);
		my_phone_number3 =
				new JTextField(PHONE_NUM_SIZE + 1);

		my_month = new JComboBox(MONTHS);
		my_day = new JComboBox();
		my_year = new JComboBox();

		my_start_hour = new JComboBox();
		my_start_min = new JComboBox();
		my_end_hour = new JComboBox();
		my_end_min = new JComboBox();

		my_number_items =
				new JTextField("0", PHONE_NUM_SIZE + 1);
		my_comment = new JTextArea();
		my_comment.setLineWrap(true);

		my_submit = new JButton(SUBMIT);
		my_clear = new JButton(CLEAR);

		create_hour_combo(my_start_hour);
		create_hour_combo(my_end_hour);
		create_min_combo(my_start_min);
		create_min_combo(my_end_min);
		create_year_combo(my_year);
		set_day_combo(my_day);

		my_month.addActionListener(new MonthListener());
		my_year.addActionListener(new YearListener());
		my_submit.addActionListener(new SubmitListener());
		my_clear.addActionListener(new ClearListener());

		onFrameNorth();
		onFrameMid();
		onFrameSouth();

		my_ua = ua;
		my_ps = ps;
	}

	private void onFrameNorth() {
		final JPanel north = new JPanel(new SpringLayout());

		final JLabel npo_label =
				new JLabel(NPO_NAME, JLabel.TRAILING);
		north.add(npo_label);
		north.add(my_npo_name);
		my_npo_name.setText(my_user.getNPO());
		my_npo_name.setEditable(false);

		final JLabel phone_label =
				new JLabel(PHONE, JLabel.TRAILING);
		final JPanel phone_group = new JPanel();
		phone_group.add(new JLabel("("));
		phone_group.add(my_phone_number1);
		phone_group.add(new JLabel(") -"));
		phone_group.add(my_phone_number2);
		phone_group.add(new JLabel("-"));
		phone_group.add(my_phone_number3);
		north.add(phone_label);
		north.add(phone_group);

		final JLabel auction_date_label =
				new JLabel(AUCTION_DATE, JLabel.TRAILING);
		final JPanel date_group = new JPanel();
		final JLabel dash1 = new JLabel("/");
		final JLabel dash2 = new JLabel("/");
		date_group.add(my_month);
		date_group.add(dash1);
		date_group.add(my_day);
		date_group.add(dash2);
		date_group.add(my_year);
		north.add(auction_date_label);
		north.add(date_group);

		final JLabel start_label =
				new JLabel(START_TIME, JLabel.TRAILING);
		final JPanel start_group = new JPanel();
		final JLabel colon1 = new JLabel(":");
		start_group.add(my_start_hour);
		start_group.add(colon1);
		start_group.add(my_start_min);
		north.add(start_label);
		north.add(start_group);

		final JLabel end_label =
				new JLabel(END_TIME, JLabel.TRAILING);
		final JPanel end_group = new JPanel();
		final JLabel colon2 = new JLabel(":");
		end_group.add(my_end_hour);
		end_group.add(colon2);
		end_group.add(my_end_min);
		north.add(end_label);
		north.add(end_group);

		final JLabel number_items_label =
				new JLabel(NUMBER_ITEMS, JLabel.TRAILING);
		final JPanel number_panel = new JPanel();
		number_panel.add(my_number_items);
		north.add(number_items_label);
		north.add(number_panel);

		SpringUtilities.makeCompactGrid(north, 6, 2, 6, 6,
				6, 3);

		my_Frame.add(north, BorderLayout.NORTH);
	}

	private void onFrameMid() {
		final JPanel mid = new JPanel();

		final JLabel comment_label = new JLabel(COMMENT);
		final JPanel comment_panel =
				new JPanel(new BorderLayout());
		comment_panel.add(comment_label, BorderLayout.EAST);
		final JPanel comment_west =
				new JPanel(new BorderLayout());
		comment_west.add(comment_panel, BorderLayout.NORTH);

		final JScrollPane areaScrollPane =
				new JScrollPane(my_comment);
		areaScrollPane.setPreferredSize(new Dimension(
				COMMENT_COL, COMMENT_ROW));

		mid.add(comment_west);
		mid.add(areaScrollPane);

		my_Frame.add(mid, BorderLayout.CENTER);
	}

	private void onFrameSouth() {
		final JPanel south = new JPanel();
		south.add(my_submit);
		south.add(my_clear);
		my_Frame.add(south, BorderLayout.SOUTH);
	}

	private void
			create_hour_combo(final JComboBox the_hour) {
		for (int i = 0; i < HOUR_IN_DAY; ++i) {
			the_hour.addItem(i);
		}
	}

	private void create_min_combo(final JComboBox the_min) {
		for (int i = 0; i < MIN_IN_HOUR; ++i) {
			the_min.addItem(i);
		}
	}

	private void
			create_year_combo(final JComboBox the_year) {
		for (int i = 0; i < YEARS_FUTURE; ++i) {
			the_year.addItem(Calendar.getInstance().get(
					Calendar.YEAR)
					+ i);
		}
	}

	private void set_day_combo(final JComboBox the_day) {
		the_day.removeAllItems();
		final Calendar cld = Calendar.getInstance();
		cld.clear();
		cld.set(Calendar.YEAR,
				(Integer) my_year.getSelectedItem());
		cld.set(Calendar.MONTH, my_month.getSelectedIndex());
		for (int i = 1; i <= cld
				.getActualMaximum(Calendar.DAY_OF_MONTH); ++i) {
			the_day.addItem(i);
		}
	}

	private class MonthListener implements ActionListener {
		public void actionPerformed(
				final ActionEvent the_action) {
			set_day_combo(my_day);
		}
	}

	private class YearListener implements ActionListener {
		public void actionPerformed(
				final ActionEvent the_action) {
			set_day_combo(my_day);
		}
	}

	public void start() {
		my_Frame.pack();
		my_Frame.setVisible(true);
		my_Frame.setLocationRelativeTo(null);
	}

	private class SubmitListener implements ActionListener {
		public void actionPerformed(
				final ActionEvent the_action) {
			final String phone_string =
					"(" + my_phone_number1.getText()
							+ ") - "
							+ my_phone_number2.getText()
							+ " - "
							+ my_phone_number3.getText();
			final Calendar cld = Calendar.getInstance();
			cld.clear();
			cld.set((Integer) my_year.getSelectedItem(),
					my_month.getSelectedIndex(),
					(Integer) my_day.getSelectedItem());
			final double start_time =
					((Integer) my_start_hour
							.getSelectedItem())
							+ +((Integer) (my_start_min
									.getSelectedItem()) / 60.);
			final double end_time =
					((Integer) my_end_hour
							.getSelectedItem())
							+ +((Integer) (my_end_min
									.getSelectedItem()) / 60.);

			String my_auction_name =
					my_npo_name
							+ "-"
							+ cld.getDisplayName(
									Calendar.MONTH, 2,
									Locale.ENGLISH)
							+ "-"
							+ cld.get(Calendar.DAY_OF_MONTH)
							+ "-" + cld.get(Calendar.YEAR);

			try {
				my_cldmodel.addAuction(my_auction_name,
						my_npo_name.getText(),
						phone_string, cld.getTime(),
						start_time, end_time, Integer
								.parseInt(my_number_items
										.getText()),
						my_comment.getText());
				JOptionPane
						.showMessageDialog(
								null,
								"Successfully create a new auction",
								"Auction",
								JOptionPane.INFORMATION_MESSAGE);

				Auction a = null;
				List<Auction> a_list =
						my_cldmodel.getAuctions(cld
								.getTime());
				for (int i = 0; i < a_list.size(); i++) {
					if (a_list
							.get(i)
							.getNPO()
							.compareToIgnoreCase(
									my_npo_name.getText()) == 0) {
						a = a_list.get(i);
					}
				}
				AuctionGUI a_gui =
						new AuctionGUI(a, my_user);
				if (a != null) {
					AuctionFormGUI.this.my_Frame.dispose();
					a_gui.start(my_ps, my_cldmodel, my_ua);
				}
			} catch (NumberFormatException e) {
				JOptionPane.showMessageDialog(null,
						"Invalid number of items!", ERROR,
						JOptionPane.ERROR_MESSAGE);
			} catch (BadDateException e) {
				JOptionPane.showMessageDialog(null,
						"Invalid date!", ERROR,
						JOptionPane.ERROR_MESSAGE);
			} catch (BadTimeException e) {
				JOptionPane.showMessageDialog(null,
						"Invalid time!", ERROR,
						JOptionPane.ERROR_MESSAGE);
			} catch (SameNpoInYearException e) {
				JOptionPane.showMessageDialog(null,
						"Invalid NPO!", ERROR,
						JOptionPane.ERROR_MESSAGE);
			} catch (AuctionLimitReachedException e) {
				JOptionPane
						.showMessageDialog(
								null,
								"Exceed the maximum allowed auction!",
								ERROR,
								JOptionPane.ERROR_MESSAGE);
			}
		}
	}

	private class ClearListener implements ActionListener {
		public void actionPerformed(
				final ActionEvent the_action) {
			my_phone_number1.setText("");
			my_phone_number2.setText("");
			my_phone_number3.setText("");
			my_number_items.setText("0");
			my_comment.setText("");
			my_month.setSelectedIndex(0);
			my_day.setSelectedIndex(0);
			my_year.setSelectedIndex(0);
			my_start_hour.setSelectedIndex(0);
			my_start_min.setSelectedIndex(0);
			my_end_hour.setSelectedIndex(0);
			my_end_min.setSelectedIndex(0);
		}
	}
}
